package com.ocom.xcxapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.ocom.common.entity.card.EntityXfMerchantInfo;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.xcx.PayRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.NumConvertUtil;
import com.ocom.common.utils.RequestUtil;
import com.ocom.common.utils.ResultUtil;
import com.ocom.redis.util.RedisUtil;
import com.ocom.xcxapi.client.HumanClientService;
import com.ocom.xcxapi.client.PayConfigClientService;
import com.ocom.xcxapi.client.PayHandleClientService;
import com.ocom.xcxapi.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

@Slf4j
@Service
public class PayServiceImpl implements PayService {

    @Autowired
    private PayConfigClientService payConfigClientService;

    @Value("${paycenter.url}")
    private String payCenterUrl;

    @Autowired
    private PayHandleClientService payHandleClientService;

    @Autowired
    HumanClientService humanClientService;

    @Resource
    private RedisUtil redisUtil;


    private  static Map<Integer , String> payCenter = new HashMap(){
        {
            put(0, "http://127.0.0.1:8080/ocom_pay/");
            put(1, "http://192.168.3.123:32880/ocom_pay/");
            put(2, "http://192.168.185.142:33880/ocom_pay/");
        }
    };

    @Override
    public Result pay(PayRequest payRequest) {
        Gson gson=new Gson();

        String comIdHex = payRequest.getOrderNo().substring(2,8);
        Integer comId = NumConvertUtil.HexStringToInt(comIdHex);
        payRequest.setComId(comId.longValue());
        //1、获取支付通道
        Integer merchId = 0;
        //获取消费记录
        Result orderResult =payHandleClientService.getOrderInfo(payRequest.getComId(),payRequest.getOrderNo(),"");
        if(!orderResult.getCode().equals(200)){
            log.info("获取支付记录失败：【{}】",orderResult);
            return ResultUtil.error(ResultEnum.Err_805);
        }
        EntityXfRecordProcess entityXfRecordProcess = JSON.parseObject(JSON.toJSONString(orderResult.getData()), EntityXfRecordProcess.class);
        payRequest.setPId(entityXfRecordProcess.getPId());
        int amount = entityXfRecordProcess.getRealMoney().intValue();

        Result result = payConfigClientService.MerchPageInfo(payRequest.getComId(), merchId);
        log.info("随行付支付-获取支付通道参数 【{}】",result);
        if(result.getCode()!=200){
            log.info("支付参数获取失败 【{}】 ", result);
            return ResultUtil.error(ResultEnum.Err_4023);
        }

        EntityXfMerchantInfo entityXfMerchantInfo = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),EntityXfMerchantInfo.class);

        //获取用户信息
        Result result22 = humanClientService.getXfUserInfo(payRequest.getComId(),payRequest.getPId());
        log.info("随行付支付-支付人员信息 【{}】 ", result22);
        if(result22.getCode()!=200){
            return ResultUtil.error(ResultEnum.Err_4023);
        }

        String url = getPayCenterUrl(payRequest.getComId(),entityXfMerchantInfo.getCompanyId());

        //获取请求ip地址

        Map<String,Object> map =new HashMap<>();
        map.put("comId", payRequest.getComId());
        map.put("totalFee",amount);
        String RealUrl=url+"unifiedpreorder/lordesau.do";

        Map<String,Object> stringObjectMap =new HashMap<>();
        stringObjectMap.put("company_id",entityXfMerchantInfo.getCompanyId());
        stringObjectMap.put("password",entityXfMerchantInfo.getPassword());
        stringObjectMap.put("user_name",entityXfMerchantInfo.getUserName());

        stringObjectMap.put("pos_no","00000000");
        stringObjectMap.put("devsnip","127.0.0.1");
        stringObjectMap.put("out_trade_no", entityXfRecordProcess.getPlatOrderNo());
        stringObjectMap.put("subject","余额充值");
        stringObjectMap.put("total_amount",amount);
        stringObjectMap.put("fee_type","CNY");
        stringObjectMap.put("trade_type","XCXAPI");
        stringObjectMap.put("payway",3);
        stringObjectMap.put("body",payRequest.getComId().toString());
        stringObjectMap.put("operator","admin");
        stringObjectMap.put("openid",payRequest.getOpenId());
        RequestUtil requestUtil=new RequestUtil();

        log.info("地址【{}】  参数【{}】",RealUrl,stringObjectMap);

        Map<String, String> re = requestUtil.doPostJson(RealUrl,JSON.toJSONString(stringObjectMap));

        Result result3 = gson.fromJson(gson.toJson(re),Result.class);

        log.info("返回【{}】  ",result3);

        if(result3 == null || result3.getCode()!=200){
            return ResultUtil.info(result3.getCode(),result3.getMsg(),result3.getData());
            /**
             Map<String,Object> map =new HashMap<>();
             map.put("outTradeNo","nrFqKJYvQooEtXdTXVKKHVPkkgXxj3Lq");
             map.put("timeStamp","1657084272");
             map.put("nonceStr","B7RhLtRQ5XkpLk0h");
             map.put("appid","wx7b35e13388684b68");
             map.put("sign","E315466DA8AFD4709DED09A3BB6A0568");
             map.put("mchId","1483737272");
             map.put("prepayId","wx06131112573065de8b46e350ebafdc0000");
             return ResultUtil.success(map);
             **/
        }

        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(result3.getData()));
        JSONObject jsonObject1 = JSON.parseObject(jsonObject.getString("prepay_id"));

        map.put("outTradeNo",jsonObject.getString("ordNo"));
        map.put("timeStamp",jsonObject.getString("payTimeStamp"));
//        map.put("timeStamp",jsonObject1.getString("timeStamp"));
//        map.put("nonceStr",jsonObject1.getString("nonce_str"));
        map.put("nonceStr",jsonObject.getString("paynonceStr"));
        map.put("appid",jsonObject.getString("payAppId"));
//        map.put("sign",jsonObject1.getString("sign"));
        map.put("sign",jsonObject.getString("paySign"));
//        map.put("mchId",jsonObject1.getString("mch_id"));
        map.put("mchId",jsonObject.getString("subMchId"));
//        map.put("signType",jsonObject1.getString("signType"));
        map.put("signType",jsonObject.getString("paySignType"));

//        if(CommonUtil.isNull(jsonObject1.getString("signType"))){
//            map.put("signType","MD5");
//        }
//
//        if(CommonUtil.isNull(jsonObject1.getString("appid"))){
//            map.put("appid",jsonObject1.getString("appId"));
//        }
//        if(CommonUtil.isNull(jsonObject1.getString("nonce_str"))){
//            map.put("nonceStr",jsonObject1.getString("nonceStr"));
//        }
//        if(CommonUtil.isNull(jsonObject1.getString("sign"))){
//            map.put("sign",jsonObject1.getString("paySign"));
//        }
//
        String prepayId  = jsonObject.getString("prepay_id");
        if(CommonUtil.isNull(jsonObject.getString("prepay_id"))){
//            prepayId  = jsonObject1.getString("package");
            prepayId  = jsonObject.getString("payPackage");
        }
//
//        map.put("mchId",jsonObject1.getString("mch_id"));

        if(prepayId!=null && prepayId.startsWith("prepay_id=")){
            prepayId=prepayId.substring(10);
        }
        map.put("prepayId",prepayId);
        map.put("type",1);

        return ResultUtil.success(map);
    }

    public String getPayCenterUrl(Long comId, String companyId) {

        if (comId == null) {
            return payCenter.get(0);
        }

        Object payUrl = redisUtil.get("payCenter:#comId:"+comId+"#companyId:" + companyId);
        if (payUrl != null) return payCenter.get((Integer) payUrl);

        if (!payCenterUrl.equals("dev")) {
            if (companyId.length() > 0 && Character.isDigit(companyId.charAt(companyId.length() - 1))) {
                redisUtil.set("payCenter:#comId:"+comId+"#companyId:" + companyId, 1, Long.valueOf(60 * 60 * 4));
                return payCenter.get(1);
            } else {
                companyId = companyId.toUpperCase(Locale.ROOT);
                char lastChar = companyId.charAt(companyId.length() - 1);
                int indexA = (int) lastChar;
                indexA -= 63;  //A -> 2 B->3 类推
                redisUtil.set("payCenter:#comId:"+comId+"#companyId:" + companyId, indexA, Long.valueOf(60 * 60 * 4));
                return payCenter.get(indexA);
            }

        } else {
            redisUtil.set("payCenter:#comId:"+comId+"#companyId:" + companyId, 0, Long.valueOf(60 * 60 * 4));
            return payCenter.get(0);
        }

    }
}
